先來解說圖:
E/A/V/T/op
的形式記著真實世界的資訊。t1
對應的資料庫,也就是 t1
時間之前的所有資料原子聚合起來所對應的資料庫。時間 t1
對應了 2024-01-01
的時間,而現在已經是 t3
時間了。當我們處於 t3
時間,有辦法透過查詢資料庫來取得 t1
時間對應的資料庫的狀態嗎?這種需求在 RDBMS 的話,頗麻煩;在以事件溯源為基礎而設計的 Datomic 的話,透過 d/as-of
這個 API 就可以達成。
e | a | v | tx | added |
---|---|---|---|---|
0x00000c00000003e9 | :db/txInstant | Mon Dec 31 19:00:00 | 0xc00000003e9 | true |
0x00001000000003ea | :item/id | DLC-042 | 0xc00000003e9 | true |
0x00001000000003ea | :item/description | Dilitihium Crystals | 0xc00000003e9 | true |
0x00001000000003ea | :item/count | 100 | 0xc00000003e9 | true |
0x00000c00000003eb | :db/txInstant | Thu Jan 31 19:00:00 | 0xc00000003eb | true |
0x00001000000003ea | :item/count | 100 | 0xc00000003eb | false |
0x00001000000003ea | :item/count | 250 | 0xc00000003eb | true |
0x00000c00000003ec | :db/txInstant | Thu Feb 27 19:00:00 | 0xc00000003ec | true |
0x00001000000003ea | :item/count | 250 | 0xc00000003ec | false |
0x00001000000003ea | :item/count | 50 | 0xc00000003ec | true |
0x00000c00000003ed | :db/txInstant | Mon Mar 31 20:00:00 | 0xc00000003ed | true |
0x00000c00000003ed | :tx/error | true | 0xc00000003ed | true |
0x00001000000003ea | :item/count | 50 | 0xc00000003ed | false |
0x00001000000003ea | :item/count | 9999 | 0xc00000003ed | true |
0x00000c00000003ee | :db/txInstant | Wed May 14 20:00:00 | 0xc00000003ee | true |
0x00001000000003ea | :item/count | 9999 | 0xc00000003ee | false |
0x00001000000003ea | :item/count | 100 | 0xc00000003ee | true |
t3
的查詢(def db (d/db conn))
(d/pull db '[*] [:item/id "DLC-042"])
=> {:db/id 55301036830621764,
:item/id "DLC-042",
:item/description "Dilitihium Crystals",
:item/count 100}
t1
之後,做一模一樣的查詢;; 注意:db 是 t3 時間對應的資料庫。
;; (d/as-of db t1) 會傳回 t1 時間對應的資料庫
(def as-of-eoy-2013 (d/as-of db #inst "2014-01-01"))
(d/pull as-of-eoy-2013 '[*] [:item/id "DLC-042"])
=> {:db/id 55301036830621764,
:item/id "DLC-042",
:item/description "Dilitihium Crystals",
:item/count 250}
這邊我們要做個詞彙歧義的解說:關於「資料庫」一詞的兩個含義。
當我們談「資料庫過濾器」時,此處的資料庫是第二個含義的資料庫。而 Datomic 總共提供了三個內建的資料庫過濾器:
as-of
: 篩選某個特定時間之前的所有資料原子。since
:篩選某個特定時間之後的所有資料原子。history
:讓資料庫包含未經聚合處理資料原子,特別是包含了 added
為 false
的資料原子。這讓我們可以看到對某一個資料實體的所有修改。